In [1]:
#include <thread>
#include <iostream>
#include <vector>

std::recursive_mutex
This mutex can be acquired several times by the same thread. a both fuggvenyben ha sima mutex lenne, akkor a mul fv mar nem tudna meghivni ua a mutexre a lockot igy deadlock lenne, ezt kuszoboli ki a recursive mutex

In [ ]:
struct Complex {
    std::recursive_mutex mutex;
    double i;

    Complex() : i(1) {}

    void mul(double x){
        std::lock_guard<std::recursive_mutex> lock(mutex);
        i *= x;
    }

    void div(double x){
        std::lock_guard<std::recursive_mutex> lock(mutex);
        i /= x;
    }

    void both(double x, double y){
        std::lock_guard<std::recursive_mutex> lock(mutex);
        mul(x);
        div(y);
    }
};

// std::recursive_mutex. This mutex can be acquired several times by the same thread.
Complex complex;
complex.both(32, 23);
std::cout << complex.i << "\n";

Timed locking

Sometimes, you doesn't want a thread to wait ad infinitum for a mutex. For example, if your thread can do something else when waiting for the thread. For this purpose, the standard library has a solution: std::timed_mutex and std::recursive_timed_mutex (if you need the recursivity properties of the mutex). You have access to the same functions as a std::mutex: lock() and unlock(), but you have also two new functions: try_lock_for() and try_lock_until().

The first one is also the most useful. It allows you to set a timeout after when the function automatically returns even if the lock was not acquired. The function returns true if the lock has been acquired, false otherwise. Let's try it with a simple example:

In [ ]:
std::timed_mutex mutex;

void work(){
    std::chrono::milliseconds timeout(10);

    while(true){
        if(mutex.try_lock_for(timeout)){
            std::cout << std::this_thread::get_id() << ": do work with the mutex" << std::endl;

            std::chrono::milliseconds sleepDuration(250);
            std::this_thread::sleep_for(sleepDuration);

            mutex.unlock();

            std::this_thread::sleep_for(sleepDuration);
        } else {
            std::cout << std::this_thread::get_id() << ": do work without mutex" << std::endl;

            std::chrono::milliseconds sleepDuration(100);
            std::this_thread::sleep_for(sleepDuration);
        }
    }
}

//Timed locking//

std::thread t1(work);
std::thread t2(work);

t1.join();
t2.join();

Call once
Sometimes you want a function to be called only once no matter the number of threads that are used. Imagine a function that has two parts. The first part has to be called only once and the second has to be executed every time the function gets called. We can use the std::call_once function to fix this problem very easily. Here is an example using this mechanism:

Each std::call_once is matched to a std::once_flag variable. Here I put a closure to be executed only once, but a function pointer or a std::function will make the trick.

In [ ]:
std::once_flag flag;

void do_something() {
    std::call_once(flag, [](){std::cout << "Called once" << std::endl;});

    std::cout << "Called each time" << std::endl;
}

//Call once//

std::thread t1(do_something);
std::thread t2(do_something);
std::thread t3(do_something);
std::thread t4(do_something);

t1.join();
t2.join();
t3.join();
t4.join();